<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Validator;
use Carbon\Carbon; 
// Model
use App\Models\Order;
use App\Models\BetNumber;
use App\Models\WinningHistory;
use App\Models\Machine;
use App\Models\Region;
use App\Models\SpecialNumber;
use Illuminate\Support\Facades\DB;
use Log;

class OrderController extends Controller
{
    //
    // ================= Admin API ================ //
    public function getRealTimeOrders(Request $request) 
    {
        $machine_number = $request->machine_number ? $request->machine_number : '';
        $serial_number = $request->serial_number ? $request->serial_number : '';
        $bet_number = $request->bet_number ? $request->bet_number : '';
        $regions = $request->regions ? explode(',', rtrim($request->regions, ',')) : [];
        $order_column = $request->order_column ? ltrim($request->order_column, 'order.') : '';
        $order_by = $request->order_by ? $request->order_by : '';
        $order_base = $request->order_base ? $request->order_base : 'number';

        // =========================== by bet_number ========================= //
        $betNumberQuery = BetNumber::whereHas('order', function($query) use ($machine_number, $serial_number, $regions) {
                                        if($machine_number){
                                            $query->where('machine_number', $machine_number);
                                        }
                                        $query->where('serial_number', 'LIKE', '%' . $serial_number . '%');
                                        if($regions) {
                                            foreach($regions as $region) {
                                                $query->where('belong_to', 'LIKE', '%' . $region . '%');
                                            }
                                        }
                                    })->with(['order' => function($query) { 
                                        return $query->select('id', 'machine_number', 'serial_number', 'belong_to', 'is_winner', 'total_winning_amount', 'is_paid', 'paid_at', 'is_deleted', 'deleted_at', 
                                        DB::raw('date_add(created_at,INTERVAL -4 hour) created_at, date_add(updated_at,INTERVAL -4 hour) updated_at'));
                                    }]);
        if ($request->start) {
            //加12小时
            $request->start = $request->start . ' 04:00:00';
            $betNumberQuery->where('created_at', '>=', $request->start);
        }
        if ($request->end) {
            $request->end = date('Y-m-d H:i:s',strtotime('+4 hours',  strtotime($request->end . ' 23:59:59')));
            $betNumberQuery->where('created_at', '<=', $request->end);
        }
        if ($bet_number) {
            $betNumberQuery->where('bet_number', $bet_number);
        }
        
        if($order_base == 'number') {
            $betNumberQuery->orderByRaw('LENGTH('.$order_column.') '.$order_by)
                            ->orderBy($order_column, $order_by);
        }
        $data['betNumbers'] = $betNumberQuery->select('id', 'order_id', 'bet_number', 'is_pool', 'bet_money', 'prizes', 'is_winner', 'rank', 'checked_winning', 'winning_payment_time', 
        DB::raw('date_add(created_at,INTERVAL -4 hour) created_at, date_add(updated_at,INTERVAL -4 hour) updated_at'))->orderBy('created_at', 'DESC')
                                            ->get();
        $data['totalRevenue'] = $betNumberQuery->sum('bet_money');

        // ========================== by order ============================= //
        $ordersQuery = Order::whereHas('betNumbers', function($query) use ($bet_number,$machine_number) {
                            if ($bet_number) {
                                $query->where('bet_number', $bet_number);
                            }
                            if ($machine_number) {
                                $query->where('machine_number', $machine_number);
                            }
                            
                            })->with(['betNumbers' => function($query) use ($bet_number) {
                                $query->select('id', 'order_id', 'bet_number', 'is_pool', 'bet_money', 'prizes', 'is_winner', 'rank', 'checked_winning', 'winning_payment_time', 
                                DB::raw('date_add(created_at,INTERVAL -4 hour) created_at, date_add(updated_at,INTERVAL -4 hour) updated_at'));
                                if ($bet_number) {
                                    $query->where('bet_number', $bet_number);
                                }
                            }])->where('serial_number', 'LIKE', '%'. $serial_number .'%');
        if($regions) {
            foreach($regions as $region) {
                $ordersQuery->where('belong_to', 'LIKE', '%' . $region . '%');
            }
        }
        if ($request->start) {
            $ordersQuery->where('created_at', '>=', $request->start);
        }
        if ($request->end) {
            $ordersQuery->where('created_at', '<=', $request->end);
        }
        if ($order_base == 'order') {
            $ordersQuery->orderByRaw('LENGTH('.$order_column.') '.$order_by)
                        ->orderBy($order_column, $order_by);
        }
        $data['orders'] = $ordersQuery->select('id', 'machine_number', 'serial_number', 'belong_to', 'is_winner', 'total_winning_amount', 'is_paid', 'paid_at', 'is_deleted', 'deleted_at', 
        DB::raw('date_add(created_at,INTERVAL -4 hour) created_at, date_add(updated_at,INTERVAL -4 hour) updated_at, date_add(deleted_at,INTERVAL -4 hour) deleted_at'))->orderBy('created_at', 'DESC')
                                        ->get();

        return response()->json(["status" => 200, "data" => $data, "message" => "success"], 200);
    }

    public function getNumberDistributions(Request $request)
    {
        $all_machines = $request->all_machines;
        $machine_number = $request->machine_number ? $request->machine_number : '';
        $bet_number = $request->bet_number ? $request->bet_number : '';
        $is_pool = (strpos($bet_number, 'p') !== false || strpos($bet_number, 'P') !== false) ? true : false;
        $regions = $request->regions ? explode(',', rtrim($request->regions, ',')) : [];

        $betNumberQuery = BetNumber::whereHas('order', function($query) use ($all_machines, $machine_number, $regions) {
                $query->where('is_deleted', false);
            if(!$all_machines && $machine_number) {
                $query->where('machine_number', $machine_number);
            }
            if($regions) {
                foreach($regions as $region) {
                    $query->where('belong_to', 'LIKE', '%' . $region . '%');
                }
            }
        })->with(['order']);
        $machineNumberQuery = Order::whereHas('betNumbers', function($query) use ($bet_number) {
                                    $query->where('bet_number', 'LIKE', '%' . $bet_number . '%');
                                })->where('is_deleted', false)
                                ->where('machine_number', 'LIKE', '%' . $machine_number . '%');
        if ($request->start) {
            $request->start = $request->start . ' 04:00:00';
            $betNumberQuery->where('created_at', '>=', $request->start);
            $machineNumberQuery->where('created_at', '>=', $request->start);
        }
        if ($request->end) {
            $request->end = date('Y-m-d H:i:s',strtotime('+4 hours',  strtotime($request->end . ' 23:59:59')));
            $betNumberQuery->where('created_at', '<=', $request->end);
            $machineNumberQuery->where('created_at', '<=', $request->end);
        }
        if(!$all_machines && $bet_number) {
            $betNumberQuery->where('bet_number', rtrim(rtrim($bet_number, 'p'), 'P'))
                            ->where('is_pool', $is_pool);
        }
        $betUnPoolNumberQuery = $betNumberQuery;
        $betPoolNumberQuery = $betNumberQuery;
        $betNumbersGroups = $betNumberQuery->orderByRaw('LENGTH(bet_number) DESC')
                                            ->orderBy('bet_number', 'DESC')
                                            ->orderBy('created_at', 'ASC')
                                            ->get()
                                            ->groupBy('is_pool');
        $betNumbersByPool = [];
        foreach($betNumbersGroups as $betNumbersGroup) {
            $betNumbersByPool[] = $betNumbersGroup->groupBy('bet_number');
        }

        $foramttedBetNumbers = [];
        $data['betStatics']['totalBetMoney'] = 0;
        $data['betStatics']['totalBetNumbers'] = 0;
        $data['betStatics']['totalPoolBetNumbers'] = 0;
        foreach($betNumbersByPool as $betNumberByPool) {
            foreach($betNumberByPool as $betNumberBySameNum) {
                $_sub_total_bet_money = 0;
                $_bet_number = '';
                $_is_pool = '';
                $_machine_number = '';
                $_serial_number = '';
                foreach($betNumberBySameNum as $betNumberByObj) {
                    $_bet_number = $betNumberByObj['bet_number'];
                    $_is_pool = $betNumberByObj['is_pool'];
                    $_machine_number = $betNumberByObj['order']['machine_number'];
                    $_serial_number = $betNumberByObj['order']['serial_number'];
                    if($regions) {
                        foreach($regions as $region) {
                            if(strpos($betNumberByObj['order']['belong_to'], $region) !== false) {
                                $_sub_total_bet_money += $betNumberByObj['bet_money'];
                                $data['betStatics']['totalBetMoney'] += $betNumberByObj['bet_money'];
                            }
                        }
                    } else {
                        $_sub_total_bet_money += $betNumberByObj['bet_money'] * count(explode("+", $betNumberByObj['order']['belong_to']));
                        $data['betStatics']['totalBetMoney'] += $betNumberByObj['bet_money'] * count(explode("+", $betNumberByObj['order']['belong_to']));
                    }
                }
                $foramttedBetNumberObj = array(
                    'bet_number' => $_bet_number,
                    'is_pool' => $_is_pool,
                    'sub_total_bet_money' => $_sub_total_bet_money,
                    'machine_number' => $_machine_number,
                    'serial_number' => $_serial_number,
                );
                array_push($foramttedBetNumbers, $foramttedBetNumberObj);
                $data['betStatics']['totalBetNumbers'] += 1;
                if ($_is_pool) {
                    $data['betStatics']['totalPoolBetNumbers'] += 1;
                }
            }
        }

        $data['betNumbers'] = $foramttedBetNumbers;

        $data['betStatics']['totalMachines'] = $machineNumberQuery->distinct()->count('machine_number');

        return response()->json(["status" => 200, "data" => $data, "message" => "success"], 200);
    }

    public function getTotalOrders(Request $request)
    {
        
        ini_set('memory_limit', '-1');
        
        $all_machines = $request->all_machines ? $request->all_machines : true;
        $machine_number = $request->machine_number ? $request->machine_number : '';
        $order_column = $request->order_column ? $request->order_column : 'machine_number';
        $order_by = $request->order_by ? $request->order_by : 'ASC';
        $start = $request->start;
        $end = $request->end;

        $ordersQuery = Order::with(['betNumbers', 'machine'])
                            ->where('is_deleted', false);
        if ($machine_number != '') {
            $ordersQuery->where('machine_number', $machine_number);
        }
        if ($start) {
            $start = $start . ' 04:00:00';
            $ordersQuery->where('created_at', '>=', $start);
        }
        if ($end) {
            $end = date('Y-m-d H:i:s',strtotime('+4 hours',  strtotime($end . ' 23:59:59')));
            $ordersQuery->where('created_at', '<=', $end);
        }

        if ($machine_number != '') {
            $ordersGroups = $ordersQuery->orderByRaw('LENGTH('.$order_column.') '.$order_by)
                                        ->orderBy($order_column, $order_by)
                                        ->orderBy('created_at', 'DESC')
                                        ->get()
                                        ->groupBy(function($date) {
                                            return Carbon::parse($date->created_at)->subHours(4)->format('Y-m-d');
                                        });
        } else {
            $ordersGroups = $ordersQuery->orderByRaw('LENGTH('.$order_column.') '.$order_by)
                                        ->orderBy($order_column, $order_by)
                                        ->orderBy('created_at', 'DESC')
                                        ->get()
                                        ->groupBy('machine_number');
        }
//        return response()->json(["status" => 200, "data" => $ordersGroups, "message" => "success"], 200);

        $formattedOrders = [];
        foreach($ordersGroups as $ordersGroup) {
            $_machine_number = '';
            $_date = ($start == $end) ? $start : '';
            $_bet_money = 0;
            $_commission = 0;
            $_prizes = 0;
            $_redemption_amount = 0;
            $_sub_total_bet_money = 0;
            foreach($ordersGroup as $order) {
                $_date = $machine_number != '' ? Carbon::parse($order->created_at)->subHours(4)->format('Y-m-d') : $_date;
                $_machine_number = $order->machine_number;
                if (!empty($order->machine)){
                    $_commission = $order->machine->commission;
                }
                foreach($order->betNumbers as $betNumber) {
                    $_bet_money += $betNumber->bet_money;
                    $_sub_total_bet_money += $betNumber->bet_money * count(explode("+", $order->belong_to));
                    $_prizes += $betNumber->prizes;
                    if($order->is_paid) {
                        $_redemption_amount += $betNumber->prizes;
                    }
                }
            }
            if ($_commission != 0){
                array_push($formattedOrders, array(
                    'machine_number' => $_machine_number,
                    'date' => $_date,
                    'bet_money' => $_bet_money,
                    'sub_total_bet_money' => $_sub_total_bet_money,
                    'commission' => $_commission,
                    'prizes' => $_prizes,
                    'redemption_amount' => $_redemption_amount
                ));
            }
           
        }

        $data['orders'] = $formattedOrders;

        return response()->json(["status" => 200, "data" => $data, "message" => "success"], 200);
    }

    public function getWinningHistory(Request $request)
    {
        $validator = Validator::make($request->all(), [
    		'machine_number' => 'required',
    		'start' => 'required',
    		'end' => 'required',
    	]);

    	if ($validator->fails()) {
    		return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        }

        $machine_number = $request->machine_number ? $request->machine_number : '';
        $start = $request->start;
        $end = $request->end;
        $serial_number = '';
        $bet_number = '';

        $regions = Region::orderBy('id', 'ASC')->get();
        $winningHistoryArr = [];
        foreach($regions as $region) {
            $winningHistoryArr[$region->region_key]['region_name'] = $region->region_name;
            $winningHistoryArr[$region->region_key]['general_prizes_rank1_digit4'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'general', 1, 4, $start, $end);
            $winningHistoryArr[$region->region_key]['general_prizes_rank2_digit4'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'general', 2, 4, $start, $end);
            $winningHistoryArr[$region->region_key]['general_prizes_rank3_digit4'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'general', 3, 4, $start, $end);
            $winningHistoryArr[$region->region_key]['general_prizes_rank1_digit3'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'general', 1, 3, $start, $end);
            $winningHistoryArr[$region->region_key]['general_prizes_rank2_digit3'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'general', 2, 3, $start, $end);
            $winningHistoryArr[$region->region_key]['general_prizes_rank3_digit3'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'general', 3, 3, $start, $end);
            $winningHistoryArr[$region->region_key]['general_prizes_rank1_digit2'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'general', 1, 2, $start, $end);
            $winningHistoryArr[$region->region_key]['general_prizes_rank2_digit2'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'general', 2, 2, $start, $end);
            $winningHistoryArr[$region->region_key]['general_prizes_rank3_digit2'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'general', 3, 2, $start, $end);

            $winningHistoryArr[$region->region_key]['grand_prizes_digit4'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'grand', 1, 4, $start, $end);
            $winningHistoryArr[$region->region_key]['grand_prizes_digit3'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'grand', 1, 3, $start, $end);
            $winningHistoryArr[$region->region_key]['grand_prizes_digit2'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'grand', 1, 2, $start, $end);
            $winningHistoryArr[$region->region_key]['consolation_prizes'] = getPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, 'consolation', 1, 4, $start, $end);
            $winningHistoryArr[$region->region_key]['total_prizes'] = getTotalPrizesFromWinningHistory($machine_number, $serial_number, $bet_number, $region->id, $start, $end);
        }

        $data['winningHistories'] = $winningHistoryArr;

        return response()->json(["status" => 200, "data" => $data, "message" => "success"], 200);
    }

    public function getOrderInfomations(Request $request)
    {
        // echo 1111;die;
        $machine_number = $request->machine_number ? $request->machine_number : '';
        $bet_number = $request->bet_number ? $request->bet_number : '';
        $serial_number = $request->serial_number ? $request->serial_number : '';
        $winning_order = $request->winning_order;
        $unwinning_order = $request->unwinning_order;
        $paid_order = $request->paid_order;
        $unpaid_order = $request->unpaid_order;
        $regions = [];
        if($request->region_K) {
            array_push($regions, 'K');
        }
        if($request->region_F) {
            array_push($regions, 'F');
        }
        if($request->region_D) {
            array_push($regions, 'D');
        }
        if($request->region_S) {
            array_push($regions, 'S');
        }
        
        $ordersQuery = Order::with(['betNumbers' => function($query) use ($bet_number, $winning_order, $unwinning_order) {
            $query->select('id', 'order_id', 'bet_number', 'is_pool', 'bet_money', 'prizes', 'is_winner', 'rank', 'checked_winning',
            DB::raw('date_add(created_at,INTERVAL -4 hour) created_at, date_add(updated_at,INTERVAL -4 hour) updated_at, date_add(winning_payment_time,INTERVAL -4 hour) winning_payment_time'));
                                $query->where('bet_number', 'LIKE', '%' . $bet_number . '%');
                                // if($winning_order && !$unwinning_order) {
                                //     $query->where('is_winner', true);
                                // } else if(!$winning_order && $unwinning_order) {
                                //     $query->where('is_winner', false);
                                // }
                            }])
                            ->where('is_deleted', false)
                            ->where('machine_number', 'LIKE', '%' . $machine_number . '%')
                            ->where('serial_number', 'LIKE', '%' . $serial_number . '%');
        if ($request->start) {
            $request->start = $request->start . ' 04:00:00';
            $ordersQuery->where('created_at', '>=', $request->start);
        }
        if ($request->end) {
            $request->end = date('Y-m-d H:i:s',strtotime('+4 hours',  strtotime($request->end . ' 23:59:59')));
            $ordersQuery->where('created_at', '<=', $request->end);
        }
        foreach($regions as $region) {
            $ordersQuery->where('belong_to', 'LIKE', '%' . $region . '%');
        }
        if($winning_order) {
            $ordersQuery->where('is_winner', true);
        }
        if($unpaid_order) {
            $ordersQuery->where('is_paid', false);
        }

        $data['orders'] = $ordersQuery->select('id', 'machine_number', 'serial_number', 'belong_to', 'is_winner', 'total_winning_amount', 'is_paid', 'is_deleted',
        DB::raw('date_add(created_at,INTERVAL -4 hour) created_at, date_add(updated_at,INTERVAL -4 hour) updated_at, date_add(deleted_at,INTERVAL -4 hour) deleted_at, date_add(paid_at,INTERVAL -12 hour) paid_at'))->orderBy('created_at', 'DESC')
                                    ->get();

        return response()->json(["status" => 200, "data" => $data, "message" => "success"], 200);
    }

    public function getWinningHistoryByBetNumberId(Request $request)
    {
        $validator = Validator::make($request->all(), [
    		'bet_number_id' => 'required',
    	]);

    	if ($validator->fails()) {
    		return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        }

        $bet_number_id = $request->bet_number_id ? $request->bet_number_id : '';
        $regions = Region::orderBy('id', 'ASC')->get();
        $winningHistoryArr = [];
        foreach($regions as $region) {
            $winningHistoryArr[$region->region_key]['region_name'] = $region->region_name;
            $winningHistoryArr[$region->region_key]['general_prizes_rank1_digit4'] = getPrizesByBetNumber($region->id, 'general', 1, 4, $bet_number_id);
            $winningHistoryArr[$region->region_key]['general_prizes_rank2_digit4'] = getPrizesByBetNumber($region->id, 'general', 2, 4, $bet_number_id);
            $winningHistoryArr[$region->region_key]['general_prizes_rank3_digit4'] = getPrizesByBetNumber($region->id, 'general', 3, 4, $bet_number_id);
            $winningHistoryArr[$region->region_key]['general_prizes_rank1_digit3'] = getPrizesByBetNumber($region->id, 'general', 1, 3, $bet_number_id);
            $winningHistoryArr[$region->region_key]['general_prizes_rank2_digit3'] = getPrizesByBetNumber($region->id, 'general', 2, 3, $bet_number_id);
            $winningHistoryArr[$region->region_key]['general_prizes_rank3_digit3'] = getPrizesByBetNumber($region->id, 'general', 3, 3, $bet_number_id);
            $winningHistoryArr[$region->region_key]['general_prizes_rank1_digit2'] = getPrizesByBetNumber($region->id, 'general', 1, 2, $bet_number_id);
            $winningHistoryArr[$region->region_key]['general_prizes_rank2_digit2'] = getPrizesByBetNumber($region->id, 'general', 2, 2, $bet_number_id);
            $winningHistoryArr[$region->region_key]['general_prizes_rank3_digit2'] = getPrizesByBetNumber($region->id, 'general', 3, 2, $bet_number_id);
            $winningHistoryArr[$region->region_key]['grand_prizes_digit4'] = getPrizesByBetNumber($region->id, 'grand', 1, 4, $bet_number_id);
            $winningHistoryArr[$region->region_key]['grand_prizes_digit3'] = getPrizesByBetNumber($region->id, 'grand', 1, 3, $bet_number_id);
            $winningHistoryArr[$region->region_key]['grand_prizes_digit2'] = getPrizesByBetNumber($region->id, 'grand', 1, 2, $bet_number_id);
            $winningHistoryArr[$region->region_key]['consolation_prizes'] = getPrizesByBetNumber($region->id, 'consolation', 1, 4, $bet_number_id);
            $winningHistoryArr[$region->region_key]['total_prizes'] = getTotalPrizesByBetNumber($region->id, $bet_number_id);
        }

        $data['winningHistories'] = $winningHistoryArr;

        return response()->json(["status" => 200, "data" => $data, "message" => "success"], 200);
    }

    public function removeOrderData(Request $request) {
        $validator = Validator::make($request->all(), [
    		'start' => 'required',
    		'end' => 'required',
    	]);

    	if ($validator->fails()) {
    		return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        }

        $request->start = $request->start . ' 04:00:00';
        $request->end = date('Y-m-d H:i:s',strtotime('+4 hours',  strtotime($request->end . ' 23:59:59')));
        $orders = Order::with(['betNumbers', 'winningHistory'])
                        ->where('created_at', '>=', $request->start)
                        ->where('created_at', '<=', $request->end)
                        ->get();
        foreach($orders as $order) {
            // winning history delete
            foreach($order->winningHistory as $history) {
                $_history = WinningHistory::find($history->id);
                $_history->delete();
            }
            // bet number delete
            foreach($order->betNumbers as $betNumber) {
                $_betNumber = BetNumber::find($betNumber->id);
                $_betNumber->delete();
            }
            $_order = Order::find($order->id);
            $_order->delete();
        }

        return response()->json(["status" => 200, "data" => "", "message" => "success"], 200);
    }






    // ================== App API ================= //
    
    public function saveOrder(Request $request) {
        
        $validator = Validator::make($request->all(), [
    		'machine_number' => 'required',
    		'serial_number' => 'required',
    		'belong_to' => 'required',
    		'bets' => 'required',
    	]);
        
    	if ($validator->fails()) {
    		return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        }

        // machine number validation
        $machine = Machine::where('machine_number', $request->machine_number)->first();
        if(!$machine) {
            return response()->json(["status" => 400, "message" => "Unknown Machine Number"], 200);
        }



        // serial number validation
        $order = Order::where('serial_number', $request->serial_number)->first();
        
        if($order) {
            return response()->json(["status" => 600, "message" => "Duplicated Serial Number"], 200);
        }
        
        // money limit validation
        $regions = explode("+", $request->belong_to);
        $bets = $request->bets;
        $save_bets = $request->bets;
        
        $temp = date('Y-m-d H:i:s',strtotime(date('Y-m-d H:i:s')) - 43200);
        $today = date('Y-m-d',strtotime(date('Y-m-d H:i:s')) - 43200);
        $tomorrow = date('Y-m-d',strtotime($temp) + 86400);

        $testArr = [];
        $ttttttt= [];
        for ($i = 0; $i < count($save_bets); $i++){
            $beti = $save_bets[$i];
            for ($j = $i + 1; $j < count($save_bets); $j++){
                $betj = $save_bets[$j];
                if ($beti["bet_number"] === $betj["bet_number"]){
                    $beti["bet_money"] = $beti["bet_money"] + $betj["bet_money"];
                    array_splice($save_bets,$j,1);
                    $j--;
                }
            }
            array_push($testArr,$beti);

        }
        foreach ($regions as $region) {
            $_region = Region::where('region_key', $region)->first();
            $region_id = $_region->id;
            foreach ($testArr as $bet) {
                // today, total bet money of the same number
                $currentTotalBetMoneyOfSameNum = BetNumber::whereHas('order', function($query) use ($region) {
                                                    $query->where('belong_to', 'LIKE', '%' . $region . '%')
                                                        ->where('is_deleted', false);
                                                })->where('bet_number', $bet['bet_number'])
                                                ->where('created_at', '>=', $today . ' 04:00:00')
                                                ->where('created_at', '<=', $tomorrow . ' 03:59:59')
                                                ->get()
                                                ->sum('bet_money');

                // today, bet money limit
                $is_pool = $bet['is_pool'];
                $digit = strlen(explode(" ", $bet['bet_number'])[0]);
                $moneyLimit = $is_pool ? $_region['digit' . $digit . '_pool_limit'] : $_region['digit' . $digit . '_limit'];
                
                // check special number
                $specialNum = SpecialNumber::where('region_id', $region_id)
                                            ->where('number', join("", explode(" ", strtoupper($bet['bet_number']))))
                                            ->first();
                if(!$specialNum) {
                    $specialNum = SpecialNumber::where('region_id', $region_id)
                                                ->where('number', join("", explode(" ", strtolower($bet['bet_number']))))
                                                ->first();
                }
                
                if($specialNum) {
                    $moneyLimit = $specialNum->limit;
                }
                
                $availableBetMoney = $moneyLimit - $currentTotalBetMoneyOfSameNum;
                // var_dump($moneyLimit,$availableBetMoney,$bet['bet_money']);die;
                if($availableBetMoney < $bet['bet_money']) {
                    $data = array(
                        'region' => $region,
                        'bet_number' => $bet['bet_number'],
                        'current_total' => $currentTotalBetMoneyOfSameNum,
                        'limit' => $moneyLimit,
                        'available' => $availableBetMoney,
                        'difference' => $bet['bet_money'] - $availableBetMoney
                    );
                    return response()->json(["status" => 400, "data" => $data, "message" => $testArr], 200);
                    break;
                }
            }
        }



        // echo date('Y-m-d H:i:s');
        // create order
        $order = Order::create([
            'machine_number' => $request->machine_number,
            'serial_number' => $request->serial_number,
            'belong_to' => $request->belong_to,
        ]);
        
        for ($i = 0; $i < count($bets); $i++){
            $bet = $bets[$i];
            BetNumber::create([
                'order_id' => $order->id,
                'bet_number' => $bet['bet_number'],
                'is_pool' => $bet['is_pool'],
                'bet_money' => $bet['bet_money'],
            ]);
        }

        $data = Order::with(['betNumbers' => function ($query) {
                            $query->orderBy('created_at', 'ASC');
                        }])
                        ->where('is_deleted', false)
                        ->where('machine_number', $request->machine_number)
                        ->where('serial_number', $request->serial_number)
                        ->orderBy('created_at', 'ASC')
                        ->get();
        return response()->json(["status" => 200, "data" => $data, "message" => "success"], 200);
    }

    public function deleteOrder(Request $request) {
        // $validator = Validator::make($request->all(), [
    	// 	'order_id' => 'required',
    	// ]);

    	// if ($validator->fails()) {
    	// 	return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        // }
        $order_id = $request->order_id ? $request->order_id : '';
        $serial_number = $request->serial_number ? $request->serial_number : '';
        if ($order_id == '' && $serial_number == '') {
            return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        }

        $order = Order::find($order_id);
        if (!$order) {
            $order = Order::where('serial_number', $serial_number)->first();
        }
        $order->is_deleted = true;
        $order->deleted_at = date('Y-m-d H:i:s');
        $order->save();

        return response()->json(["status" => 200, "data" => $order, "message" => "success"], 200);
    }

    public function getOrders(Request $request) 
    {
        $validator = Validator::make($request->all(), [
    		'machine_number' => 'required',
    	]);

    	if ($validator->fails()) {
    		return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
	}

	$number = $request->number ? $request->number : '';
        $start = $request->start ? $request->start : '';
        $end = $request->end ? $request->end : '';
        $where = [
            ['machine_number', '=', $request->machine_number]
        ];
        if ($number) {
            $where_number = ['serial_number', '=', $number];
            array_push($where, $where_number);
        }
        if ($start) {
            $where_start = ['created_at', '>', $start];
            array_push($where, $where_start);
        }
        if ($end) {
            $where_end = ['created_at', '<', $end];
            array_push($where, $where_end);
        }

        $orders = Order::with(['betNumbers' => function ($query) {
                            $query->orderBy('id', 'ASC');
                        }])
                        // ->where('is_deleted', false)
                        ->where($where)
                        ->orderBy('created_at', 'ASC')
                        ->get();

        return response()->json(["status" => 200, "data" => $orders, "message" => "success"], 200);
    }

    public function getOrdersByDate(Request $request) {
        $validator = Validator::make($request->all(), [
    		'date' => 'required',
    	]);

    	if ($validator->fails()) {
    		return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        }
        $ordersQuery = Order::with(['betNumbers' => function ($query) {
                            $query->orderBy('created_at', 'ASC');
                        }])
                        ->where('is_deleted', false);
                       
        if($request->machine_number) {
            $ordersQuery->where('machine_number', $request->machine_number);
        }
        $end = date('Y-m-d H:i:s',strtotime('+4 hours',  strtotime($request->date . ' 23:59:59')));

        $orders = $ordersQuery->where('created_at', '>=', $request->date . ' 04:00:00')
                        ->where('created_at', '<=', $end)
                        ->orderBy('created_at', 'ASC')
                        ->get();

        return response()->json(["status" => 200, "data" => $orders, "message" => "success"], 200);
    }

    public function getTodayOrders(Request $request) {
        $validator = Validator::make($request->all(), [
            'date' => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        }
        $ordersQuery = Order::with(['betNumbers' => function ($query) {
                            $query->orderBy('created_at', 'ASC');
                        }])
                        ->where('machine_number', $request->machine_number);
                       

        $end = date('Y-m-d H:i:s',strtotime('+4 hours',  strtotime($request->date . ' 23:59:59')));

        $orders = $ordersQuery->where('created_at', '>=', $request->date . ' 04:00:00')
                        ->where('created_at', '<=', $end)
                        ->get();

        return response()->json(["status" => 200, "data" => count($orders), "message" => "success"], 200);
    }
    
    public function getOrderBySerialNumber(Request $request) {
        $validator = Validator::make($request->all(), [
            'machine_number' => 'required',
    		'serial_number' => 'required',
    	]);

    	if ($validator->fails()) {
    		return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        }
        $orders = Order::with(['betNumbers' => function ($query) {
                            $query->orderBy('id', 'ASC');
                        }])
                        ->where('is_deleted', false)
                        ->where('machine_number', $request->machine_number)
                        ->where('serial_number', $request->serial_number)
                        ->orderBy('created_at', 'ASC')
                        ->first();

        return response()->json(["status" => 200, "data" => $orders, "message" => "success"], 200);
    }

    public function saveOrderPaymentStatus(Request $request) {
        $validator = Validator::make($request->all(), [
            'order_id' => 'required',
    	]);

    	if ($validator->fails()) {
    		return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        }

        $order = Order::find($request->order_id);
        if(!$order) {
            return response()->json(["status" => 400, "message" => "There is no matched data."], 200);
        }
        $order->is_paid = true;
        $order->paid_at = date('Y-m-d H:i:s');
        $order->save();

        return response()->json(["status" => 200, "data" => $order, "message" => "success"], 200);
    }

    public function getOrdersByDateRange(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'machine_number' => 'required',
    	]);

    	if ($validator->fails()) {
    		return response()->json(["status" => 400, "message" => config('messages.required_param')], 200);
        }

        $machine_number = $request->machine_number ? $request->machine_number : '';
        $start = $request->start;
        $end = $request->end;
        $order_column = 'machine_number';
        $order_by = 'ASC';



        $ordersQuery = Order::with(['betNumbers', 'machine'])
                            ->where('is_deleted', false)
                            ->where('machine_number', $machine_number);



        if ($start) {
            $start = $request->start . ' 04:00:00';
            $ordersQuery->where('created_at', '>=', $start . ' 00:00:00');
        }
        if ($end) {
            $end = date('Y-m-d H:i:s',strtotime('+4 hours',  strtotime($request->end . ' 23:59:59')));
            $ordersQuery->where('created_at', '<=', $end);
        }

        //order分组
        $ordersGroups = $ordersQuery->orderByRaw('LENGTH('.$order_column.') '.$order_by)
                                    ->orderBy($order_column, $order_by)
                                    ->orderBy('created_at', 'DESC')
                                    ->get()
                                    ->groupBy(function($date) {
                                        return Carbon::parse($date->created_at)->subHours(4)->format('Y-m-d');
                                    });


        $formattedOrders = [];
        foreach($ordersGroups as $ordersGroup) {
            $_machine_number = '';
            $_date = ($start == $end) ? $start : '';
            $_bet_money = 0;
            $_commission = 0;
            $_prizes = 0;
            $_redemption_amount = 0;
            $_sub_total_bet_money = 0;
            foreach($ordersGroup as $order) {
                $_date = $machine_number != '' ? Carbon::parse($order->created_at)->format('Y-m-d') : $_date;
                $_machine_number = $order->machine_number;
                $_commission = $order->machine->commission;
                foreach($order->betNumbers as $betNumber) {
                    $_bet_money += $betNumber->bet_money;
                    $_sub_total_bet_money += $betNumber->bet_money * count(explode("+", $order->belong_to));
                    $_prizes += $betNumber->prizes;
                    if($order->is_paid) {
                        $_redemption_amount += $betNumber->prizes;
                    }
                }
            }
            array_push($formattedOrders, array(
                'machine_number' => $_machine_number,
                'date' => $_date,
                'bet_money' => $_bet_money,
                'sub_total_bet_money' => $_sub_total_bet_money,
                'commission' => $_commission,
                'prizes' => $_prizes,
                'redemption_amount' => $_redemption_amount
            ));
        }

        $data['orders'] = $formattedOrders;

        return response()->json(["status" => 200, "data" => $data, "message" => "success"], 200);
    }
}
